package com.zzy.broker.server.codec;

import com.zzy.broker.server.message.MqttRawMessage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

public class MqttDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (!in.isReadable(2)) return; // 至少需要固定报头(1字节) + 剩余长度(至少1字节)
        
        in.markReaderIndex();
        
        // 1. 读取固定报头（第一个字节）
        byte fixedHeader = in.readByte();
        
        // 2. 解析剩余长度（可变长度编码，1-4字节）
        int remainingLength = 0;
        int multiplier = 1;
        int digit;
        int lengthBytes = 0;
        
        do {
            if (!in.isReadable()) {
                // 数据不够，重置读指针，等待更多数据
                in.resetReaderIndex();
                return;
            }
            
            digit = in.readUnsignedByte();
            remainingLength += (digit & 0x7F) * multiplier;
            multiplier *= 128;
            lengthBytes++;
            
            if (lengthBytes > 4) {
                // 剩余长度字段最多4字节
                throw new IllegalStateException("Remaining length exceeds 4 bytes");
            }
        } while ((digit & 0x80) != 0);
        
        // 3. 检查是否有足够的数据
        if (in.readableBytes() < remainingLength) {
            // 数据不够，重置读指针，等待更多数据
            in.resetReaderIndex();
            return;
        }
        
        // 4. 读取实际的消息内容（可变报头 + 负载）
        byte[] payload = new byte[remainingLength];
        in.readBytes(payload);
        
        // 5. 封装为 MqttRawMessage 传递给后续 Handler
        MqttRawMessage msg = new MqttRawMessage(fixedHeader, payload);
        out.add(msg);
    }
}
